﻿Ext.util.Sorter = Ext.extend(Object, {







    direction: "ASC",

    constructor: function (config) {
        Ext.apply(this, config);

        if (this.property == undefined && this.sorterFn == undefined) {
            throw "A Sorter requires either a property or a sorter function";
        }

        //排序方法
        this.sort = this.createSortFunction(this.sorterFn || this.defaultSorterFn);
    },

    //创建外部调用的排序方法，参数sorterFn默认为defaultSorterFn
    createSortFunction: function (sorterFn) {
        var me = this,
            property = me.property,
            direction = me.direction,
            modifier = direction.toUpperCase() == "DESC" ? -1 : 1;


        //供外部调用的排序方法，对o1和o2的指定属性结合排序方式进行比较，
        //如果o1在o2之前，返回-1；如果o1与o2并列，返回0；如果o1在o2之后，返回1
        return function (o1, o2) {
            return modifier * sorterFn.call(me, o1, o2);
        };
    },

    //默认排序方法,对o1和o2的特定属性按升序进行比较，o1 > o2时返回1，o1 = o2时返回0，o1 < o2时返回-1
    defaultSorterFn: function (o1, o2) {
        var v1 = this.getRoot(o1)[this.property],//o1中指定的属性
            v2 = this.getRoot(o2)[this.property];//o2中指定的属性

        return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
    },

    //Optional root property. This is mostly useful when sorting a Store, 
    //in which case we set the root to 'data' to make the filter pull the property out of the data object of each item
    //可选的root属性。这在给Store排序时非常有用，这种情况发生在给'data'设置根属性，以便Filter在过滤每条记录时将属性过滤掉
    getRoot: function (item) {
        return this.root == undefined ? item : item[this.root];
    }
});